﻿using CommonTool;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tool;

namespace AutoMachine
{
    /// <summary>
    /// 消息事件处理委托
    /// </summary>
    /// <param name="cmd"></param>
    public delegate void MessageReceived(string cmd);

    internal partial class Frm_TcpServer : Form
    {

        #region 窗体实例化
        /// <summary>
        /// 窗体对象实例化
        /// </summary>
        private static Frm_TcpServer _instance;
        internal static Frm_TcpServer Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new Frm_TcpServer();
                return _instance;
            }
        }
        #endregion

        internal Frm_TcpServer()
        {
            InitializeComponent();
            this.tbx_ip.Text = "192.168.1.10";
            this.tbx_port.Text = "6000";
        }

        /// <summary>
        /// 监听线程
        /// </summary>
        private Thread th_listen;

        /// <summary>
        /// 监听Socket
        /// </summary>
        private Socket listenSkt;

        /// <summary>
        /// 消息处理事件
        /// </summary>
        private MessageReceived messageReceived;

        /// <summary>
        /// 用于通讯的Socket
        /// </summary>
        public Socket commSkt;

        /// <summary>
        /// 用于存放就已经连接的Socket
        /// </summary>
        public Dictionary<string, Socket> L_connectedSocket = new Dictionary<string, Socket>();

        /// <summary>
        /// 显示消息
        /// </summary>
        /// <param name="message">要显示的内容</param>
        internal void ShowMsg(string message)
        {
            try
            {
                string curTime = DateTime.Now.ToString("HH:mm:ss");
                this.BeginInvoke((MethodInvoker)delegate
                    {
                        tbx_log.AppendText(curTime + " " + message + "\r\n");
                    });
            }
            catch (Exception ex)
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);               
            }
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="msg">要发送的信息</param>
        /// <param name="sender">消息发送者</param>
        internal void Send(string msg, string sender = "temp")
        {
            try
            {
                byte[] buffer = Encoding.Default.GetBytes(msg);
                L_connectedSocket[L_connectedSocket.Keys.ToArray()[0]].Send(buffer);
                ShowMsg("->" + msg);//显示消息
            }
            catch (Exception ex )
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);
            }

        }

        /// <summary>
        /// 消息接收
        /// </summary>
        /// <param name="obj">通讯用的Socket</param>
        public void Receieve(object obj)
        {
            try
            {
                Socket socket = obj as Socket;
                byte[] buffer = new byte[1024*1024*2];//定义一个2M的缓冲区
                while (true)
                {
                    int length = socket.Receive(buffer);
                    if (length == 0)
                    {
                        MessageBox.Show("客户端已断开连接");
                        this.BeginInvoke((MethodInvoker)delegate
                        {
                            cbx_connectedMember.Items.Remove(socket.RemoteEndPoint.ToString());
                            lbx_connectedNumber.Items.Remove(socket.RemoteEndPoint.ToString());
                            if (cbx_connectedMember.Items.Count == 0)
                                cbx_connectedMember.Text = " ";                
                        });
                        return;
                    }
                    string result = Encoding.Default.GetString(buffer, 0, length);
                    messageReceived(result);
                    this.BeginInvoke((MethodInvoker)delegate
                    {
                        if (socket.RemoteEndPoint.ToString() == cbx_connectedMember.Text && this.Visible)
                        {
                            ShowMsg("<-" + result);
                        }
                    });
                }
            }
            catch (Exception ex )
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);
                return;              
            }
        }


        public Thread th;

        /// <summary>
        /// 监听
        /// </summary>
        /// <param name="obj">监听用的Socket</param>
        private void WaitConnect(object obj)
        {
            try
            {
                Socket listenSocket = obj as Socket;
                while (true)
                {
                    commSkt = listenSocket.Accept();
                    messageReceived = MessageReceived; 
                    L_connectedSocket.Add(commSkt.RemoteEndPoint.ToString(), commSkt);
                    this.BeginInvoke((MethodInvoker)delegate
                    {
                        cbx_connectedMember.Items.Add(commSkt.RemoteEndPoint.ToString());
                        lbx_connectedNumber.Items.Add(commSkt.RemoteEndPoint.ToString());
                        if (cbx_connectedMember.Items.Count == 1)
                        {
                            cbx_connectedMember.SelectedIndex = 0;
                        }
                    });
                    th = new Thread(Receieve);
                    th.IsBackground = true;
                    th.Start(commSkt);
                }
            }
            catch (Exception ex )
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);
               
            }

        }

        /// <summary>
        /// 消息接收事件
        /// </summary>
        /// <param name="cmd"></param>
        public static void MessageReceived(string cmd)
        {
            try
            {
                switch (cmd)
                {
                    case "codeopen01":      //触发1号扫码枪扫码
                        break;
                    case "codeopen02":      //触发1号扫码枪扫码
                        break;
                    case "codeopen03":      //触发1号扫码枪扫码
                        break;
                    case "cameraopen01":      //触发1号扫码枪扫码
                        break;
                    case "cameraopen02":      //触发1号扫码枪扫码
                        break;
                    case "cameraopen03":      //触发1号扫码枪扫码
                        break;
                    default:
                        //Form_MessageBox.Instance.MessageBoxShow(string.Format("接收到未商议命令：{0}", cmd));
                        break;
                }
            }
            catch (Exception ex)
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);
            }
        }


        /// <summary>
        /// 开始监听
        /// </summary>
        public void Listen()
        {
            try
            {
                if (btn_listen.Text == "开始监听")
                {
                    listenSkt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    IPAddress ip = IPAddress.Parse(this.tbx_ip.Text.Trim());                
                    IPEndPoint point = new IPEndPoint(ip, int.Parse(this.tbx_port.Text.Trim()));
                    try
                    {
                        listenSkt.Bind(point);
                    }
                    catch (Exception ex )
                    {
                        LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                        MessageBox.Show(ex.Message);
                        return;
                    }
                    listenSkt.Listen(10);
                    th_listen = new Thread(WaitConnect);
                    th_listen.IsBackground = true;
                    th_listen.Start(listenSkt);
                    btn_listen.Text = "停止监听";
                    lbl_connectStatu.Text = "监听中";
                    lbl_connectStatu.ForeColor = Color.Green;
                    tbx_ip.Enabled = false;
                    tbx_port.Enabled = false;
                }
                else
                {
                    tbx_ip.Enabled = true;
                    tbx_port.Enabled = true;
                    btn_listen.Text = "开始监听";
                    lbl_connectStatu.Text = "未监听";
                    lbl_connectStatu.ForeColor = Color.Red;
                  //  th_listen.Suspend();
                    th_listen.Abort();
                    listenSkt.Dispose();
                    listenSkt.Close();
                }
            }
            catch (Exception ex )
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);
            }
        }


        //窗体初始化
        private void FrmTcpServer_Load(object sender, EventArgs e)
        {
            //服务器的IP地址和端口号
           
            this.tbx_ip.Text = "127.0.0.1";
            this.tbx_port.Text = "80";
        }

        //开始监听
        private void btn_listen_Click(object sender, EventArgs e)
        {
            Listen();
        }

        //发送
        private void btn_send_Click(object sender, EventArgs e)
        {
            try
            {
                if (cbx_connectedMember.SelectedIndex < 0)
                {
                    MessageBox.Show("未指定已连接客户");
                    return;
                }
                if (tbx_sendMessage.Text == string.Empty)
                {
                    MessageBox.Show("不可发送空字符");
                    return;
                }
                byte[] buffer = Encoding.Default.GetBytes(tbx_sendMessage.Text);
                L_connectedSocket[cbx_connectedMember.SelectedItem.ToString()].Send(buffer);
                ShowMsg("->:" + tbx_sendMessage.Text);
            }
            catch (Exception ex)
            {
                LogView.GetInstance().ShowLogSave(LogView.LogType.Error, ex.Message);//保存Log
                MessageBox.Show(ex.Message);
            }
        }

        //清空记录
        private void lnk_clearLog_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            tbx_log.Clear();
        }
    }
}